{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Non-Distributed FGSM Attack\n",
    "As you might have noticed, there are two different ways to use the CLI. The first one is by passing the arguments directly to the script, and the second one is by using a configuration file. Using a configuration file is a good way to keep track of the experiments you are running, and it is also a good way to avoid passing the same arguments over and over again. This notebook will show you how to use a configuration file and how to pass the arguments directly to the script for the Non-Distributed FGSM Attack."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Using a Configuration File\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 1: Create a Configuration File\n",
    "\n",
    "As a first step, you need to have a default configuration file. You can create a configuration file by running the following command:\n",
    "    \n",
    "```sh\n",
    "advsecurenet utils configs get -c fgsm_attack_config.yml -s -o ./default_fgsm_attack_config.yml\n",
    "```\n",
    "\n",
    "Here, we are also providing the `-o` flag to specify the output directory where the configuration file will be saved. You can also specify the output directory by passing the `-o` flag followed by the path to the directory where you want to save the configuration file. If you don't provide the `-o` flag, the configuration file will be saved in the current working directory with the name `fgsm_attack_config.yml`. If the file already exists, it will be overwritten. If the output path is a directory, the configuration file will be saved in that directory with the name `fgsm_attack_config.yml`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving default config to ./default_fgsm_attack_config.yml\n",
      "Generated default configuration file fgsm_attack_config.yml!\n"
     ]
    }
   ],
   "source": [
    "!advsecurenet utils configs get -c fgsm_attack_config.yml -s -o ./default_fgsm_attack_config.yml"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[34m\u001b[1m**************************************************\u001b[0m\n",
      "\u001b[31m\u001b[1mDefault configuration file for the fgsm_attack_config.yml:\n",
      "\u001b[0m\n",
      "\u001b[32m{\n",
      "    \"model\": {\n",
      "        \"model_name\": \"resnet18\",\n",
      "        \"num_input_channels\": 3,\n",
      "        \"num_classes\": 10,\n",
      "        \"pretrained\": true,\n",
      "        \"weights\": \"IMAGENET1K_V1\",\n",
      "        \"is_external\": false,\n",
      "        \"random_seed\": null,\n",
      "        \"path_configs\": {\n",
      "            \"model_arch_path\": null,\n",
      "            \"model_weights_path\": null\n",
      "        },\n",
      "        \"norm_config\": {\n",
      "            \"add_norm_layer\": false,\n",
      "            \"norm_mean\": [\n",
      "                0.5,\n",
      "                0.5,\n",
      "                0.5\n",
      "            ],\n",
      "            \"norm_std\": [\n",
      "                0.5,\n",
      "                0.5,\n",
      "                0.5\n",
      "            ]\n",
      "        }\n",
      "    },\n",
      "    \"dataset\": {\n",
      "        \"dataset_name\": \"cifar10\",\n",
      "        \"download\": true,\n",
      "        \"num_classes\": 10,\n",
      "        \"dataset_part\": \"test\",\n",
      "        \"train_dataset_path\": null,\n",
      "        \"test_dataset_path\": null,\n",
      "        \"random_sample_size\": null,\n",
      "        \"preprocessing\": {\n",
      "            \"steps\": [\n",
      "                {\n",
      "                    \"name\": \"ToImage\",\n",
      "                    \"params\": null\n",
      "                },\n",
      "                {\n",
      "                    \"name\": \"ToDtype\",\n",
      "                    \"params\": {\n",
      "                        \"dtype\": \"torch.float32\",\n",
      "                        \"scale\": true\n",
      "                    }\n",
      "                }\n",
      "            ]\n",
      "        }\n",
      "    },\n",
      "    \"dataloader\": {\n",
      "        \"default\": {\n",
      "            \"num_workers\": 4,\n",
      "            \"shuffle\": true,\n",
      "            \"drop_last\": false,\n",
      "            \"pin_memory\": true,\n",
      "            \"batch_size\": 32\n",
      "        }\n",
      "    },\n",
      "    \"device\": {\n",
      "        \"use_ddp\": false,\n",
      "        \"processor\": \"cpu\",\n",
      "        \"gpu_ids\": null\n",
      "    },\n",
      "    \"attack_procedure\": {\n",
      "        \"verbose\": true,\n",
      "        \"save_result_images\": true,\n",
      "        \"result_images_dir\": \"attack\",\n",
      "        \"result_images_prefix\": \"adv\"\n",
      "    },\n",
      "    \"attack_config\": {\n",
      "        \"target_parameters\": {\n",
      "            \"targeted\": false,\n",
      "            \"auto_generate_target\": true,\n",
      "            \"target_images_config\": {\n",
      "                \"target_images_dir\": null\n",
      "            },\n",
      "            \"target_labels_config\": {\n",
      "                \"target_labels\": [],\n",
      "                \"target_labels_path\": null,\n",
      "                \"target_labels_separator\": \",\"\n",
      "            }\n",
      "        },\n",
      "        \"attack_parameters\": {\n",
      "            \"epsilon\": 0.3\n",
      "        }\n",
      "    }\n",
      "}\u001b[0m\n",
      "\u001b[34m\u001b[1m**************************************************\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "# Let's check the content of the default config file\n",
    "!advsecurenet utils configs get -c fgsm_attack_config.yml -p"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step 2: Modify the Configuration File\n",
    "\n",
    "The default configuration file is capable of running the non-targeted `FGSM` attack on the `CIFAR10` dataset using the `ResNet18` model. You can modify the configuration file to run the FGSM attack on a different dataset or model. You can modify attack parameters, such as the epsilon value, and choose between a targeted or non-targeted attack. Additionally, you can select whether to use the GPU or CPU for the attack and decide whether to save the adversarial images\n",
    "\n",
    "For the sake of this example, we will modify the configuration file to run the `FGSM` attack on the `CIFAR10` dataset using the `VGG16` model. We will also add a *normalization layer* to the model, use the *GPU* for the attack, and *save the adversarial images*. We won't use the whole dataset for the attack, but only the *10 random samples*. Finally, we will set the epsilon value to *0.1*.\n",
    "\n",
    "\n",
    "You can find the updated configuration file [here](fgsm_attack_config.yml).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step 3: Run the Attack\n",
    "\n",
    "Now that you have created and modified the configuration file, you can run the attack by using the following command:\n",
    "\n",
    "```sh\n",
    "advsecurenet attack fgsm -c fgsm_attack_config.yml\n",
    "```\n",
    "\n",
    "**Note:** Attack success rate is calculated as the percentage of adversarial images that are misclassified by the model and the benign images that are correctly classified by the model. Since the attack runs on a different dataset than the one used to train the model, the attack success rate might be lower than expected."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Files already downloaded and verified\n",
      "\n",
      "Generating adversarial samples:   0%|\u001b[31m                  \u001b[0m| 0/1 [00:00<?, ?batch/s]\u001b[0m\u001b[A\n",
      "Generating adversarial samples: 100%|\u001b[31m██████████\u001b[0m| 1/1 [00:15<00:00, 15.42s/batch]\u001b[0m\u001b[A\n",
      "                                                                                \u001b[A\u001b[32mAttack Success Rate: 0.0000\u001b[0m\n",
      "Saving images: 100%|████████████████████████| 10/10 [00:00<00:00, 374.05image/s]\n",
      "\u001b[32mAttack completed successfully.\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "!advsecurenet attack fgsm -c fgsm_attack_config.yml"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Congratulations! You have successfully run the Non-Distributed FGSM Attack using a configuration file. You can now use the configuration file to run the attack with different parameters without having to pass the arguments directly to the script."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "adv2",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
